x11: Store last axes from device
authorCarlos Garnacho <carlosg@gnome.org>
Mon, 2 Mar 2015 17:19:16 +0000 (18:19 +0100)
committerCarlos Garnacho <carlosg@gnome.org>
Mon, 2 Mar 2015 17:57:04 +0000 (18:57 +0100)
And use these for the missing axes if the valuator mask is incomplete.
This used to work fine on tablets because the Wacom driver ensures all
valuators are sent, which is not true if using the evdev driver.

https://bugzilla.gnome.org/show_bug.cgi?id=703610

gdk/x11/gdkdevice-xi2.c
gdk/x11/gdkdevicemanager-xi2.c
gdk/x11/gdkprivate-x11.h

index b3289c0e925417cb5556cb94cf89b0ff2bd9a6be..fad867112013fc7996a5aa93480aba319680fb46 100644 (file)
@@ -51,6 +51,7 @@ struct _GdkX11DeviceXI2
 
   gint device_id;
   GArray *scroll_valuators;
+  gdouble *last_axes;
 };
 
 struct _GdkX11DeviceXI2Class
@@ -157,6 +158,7 @@ gdk_x11_device_xi2_finalize (GObject *object)
   GdkX11DeviceXI2 *device = GDK_X11_DEVICE_XI2 (object);
 
   g_array_free (device->scroll_valuators, TRUE);
+  g_free (device->last_axes);
 
   G_OBJECT_CLASS (gdk_x11_device_xi2_parent_class)->finalize (object);
 }
@@ -891,3 +893,29 @@ _gdk_x11_device_xi2_get_id (GdkX11DeviceXI2 *device)
 
   return device->device_id;
 }
+
+gdouble
+gdk_x11_device_xi2_get_last_axis_value (GdkX11DeviceXI2 *device,
+                                        gint             n_axis)
+{
+  if (n_axis >= gdk_device_get_n_axes (GDK_DEVICE (device)))
+    return 0;
+
+  if (!device->last_axes)
+    return 0;
+
+  return device->last_axes[n_axis];
+}
+
+void
+gdk_x11_device_xi2_store_axes (GdkX11DeviceXI2 *device,
+                               gdouble         *axes,
+                               gint             n_axes)
+{
+  g_free (device->last_axes);
+
+  if (axes && n_axes)
+    device->last_axes = g_memdup (axes, sizeof (gdouble) * n_axes);
+  else
+    device->last_axes = NULL;
+}
index 50c1a00711bb6f1b808394314a01390c872157db..a57ecaf8854df04a86ebb5f7b28adc23329e089f 100644 (file)
@@ -837,6 +837,7 @@ handle_device_changed (GdkX11DeviceManagerXI2 *device_manager,
     {
       _gdk_device_reset_axes (device);
       _gdk_device_xi2_unset_scroll_valuators ((GdkX11DeviceXI2 *) device);
+      gdk_x11_device_xi2_store_axes (GDK_X11_DEVICE_XI2 (device), NULL, 0);
       translate_device_classes (display, device, ev->classes, ev->num_classes);
 
       g_signal_emit_by_name (G_OBJECT (device), "changed");
@@ -939,13 +940,16 @@ translate_axes (GdkDevice       *device,
   axes = g_new0 (gdouble, n_axes);
   vals = valuators->values;
 
-  for (i = 0; i < valuators->mask_len * 8; i++)
+  for (i = 0; i < MIN (valuators->mask_len * 8, n_axes); i++)
     {
       GdkAxisUse use;
       gdouble val;
 
       if (!XIMaskIsSet (valuators->mask, i))
-        continue;
+        {
+          axes[i] = gdk_x11_device_xi2_get_last_axis_value (GDK_X11_DEVICE_XI2 (device), i);
+          continue;
+        }
 
       use = gdk_device_get_axis_use (device, i);
       val = *vals++;
@@ -970,6 +974,8 @@ translate_axes (GdkDevice       *device,
         }
     }
 
+  gdk_x11_device_xi2_store_axes (GDK_X11_DEVICE_XI2 (device), axes, n_axes);
+
   return axes;
 }
 
index d5f3e1d74f623ac98ff9317c7876a689aadfba27..c2afecf46d158421367fa4ccff3d82af724710f8 100644 (file)
@@ -247,6 +247,12 @@ gboolean  _gdk_x11_device_xi2_get_scroll_delta    (GdkX11DeviceXI2    *device,
                                                    gdouble            *delta_ret);
 void     _gdk_device_xi2_reset_scroll_valuators   (GdkX11DeviceXI2    *device);
 
+gdouble  gdk_x11_device_xi2_get_last_axis_value (GdkX11DeviceXI2 *device,
+                                                 gint             n_axis);
+
+void     gdk_x11_device_xi2_store_axes          (GdkX11DeviceXI2 *device,
+                                                 gdouble         *axes,
+                                                 gint             n_axes);
 #endif
 
 void     _gdk_x11_event_translate_keyboard_string (GdkEventKey *event);